package com.zzw.okhttp3;

import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
@Configuration
@EnableConfigurationProperties(DefaultOkhttp3ClientProperties.class)
public class Okhttp3Configuration {

    @Bean
    public DefaultOkhttp3 defaultOkhttp3() {
        return new DefaultOkhttp3();
    }

    @Bean
    @ConditionalOnMissingBean
    public OkHttpClient okHttpClient(@Autowired DefaultOkhttp3ClientProperties defaultOkhttp3ClientProperties) {
        X509TrustManager x509TrustManager = trustManager();
        final SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{x509TrustManager}, new java.security.SecureRandom());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, x509TrustManager);
        builder.hostnameVerifier((hostname, session) -> true);
        builder.connectTimeout(defaultOkhttp3ClientProperties.getConnectTimeout(), TimeUnit.SECONDS);
        builder.readTimeout(defaultOkhttp3ClientProperties.getReadTimeout(), TimeUnit.SECONDS);
        builder.writeTimeout(defaultOkhttp3ClientProperties.getWriteTimeout(), TimeUnit.SECONDS);
        builder.callTimeout(defaultOkhttp3ClientProperties.getCallTimeOut(), TimeUnit.SECONDS);
        return builder.build();
    }

    private static X509TrustManager trustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }
}
